##xxxxxxxxxxxxxxxxxxxxxxxxx C++ CMake 跨平台通用设置, 需要放在 project(xxx) 调用后面

##xxxxxxxxxxxxxxxxxxx toolchain configs; IDE 设置
# 让 generator 生成 clangd 需要的 build/compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)


##xxxxxxxxxxxxxxxxxxx c++ 语言设置
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
set(CMAKE_CXX_STANDARD 17) # C++ 标准
set(CMAKE_CXX_STANDARD_REQUIRED ON)


##xxxxxxxxxxxxxxxxxxx linux 二进制 属性
# set(CMAKE_SKIP_RPATH TRUE) # 禁用自动RPATH
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH OFF)


##xxxxxxxxxxxxxxxxxxx CUDA 全局设置
# 设置 CUDA 运行时库为动态链接
set(CMAKE_CUDA_RUNTIME_LIBRARY Shared)

##xxxxxxxxxxxxxxxxxxx 第三方库设置
#--- spdlog
# add_compile_definitions("FMT_UNICODE=0")


##xxxxxxxxxxxxxxxxxxx MSVC c++ 设置
if(MSVC)
    # 1. 强制所有 C/C++ 目标使用动态运行时
    # set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
    message(STATUS "[YMY] MSVC compiler: ${CMAKE_CXX_COMPILER}")

    set(MYTMP_CXX_CMP_OPTS_MSVC "/utf-8" "/EHsc" "/Zc:__cplusplus" "/permissive-")
    # message(STATUS "[YMY] MYTMP_CXX_CMP_OPTS_MSVC =>  ${MYTMP_CXX_CMP_OPTS_MSVC}")
    list(JOIN MYTMP_CXX_CMP_OPTS_MSVC "," MY_CXX_CMP_OPTS_NVCC)
    # message(STATUS "[YMY] MY_CXX_CMP_OPTS_NVCC => ${MY_CXX_CMP_OPTS_NVCC}")
    set(MY_CXX_CMP_OPTS_NVCC -Xcompiler="${MY_CXX_CMP_OPTS_NVCC}")
    # message(STATUS "[YMY] CMAKE_CUDA_FLAGS => ${CMAKE_CUDA_FLAGS}")

    list(JOIN MYTMP_CXX_CMP_OPTS_MSVC " " MY_CXX_CMP_OPTS_MSVC)
endif()


##xxxxxxxxxxxxxxxxxxx Linux GCC 编译选项
set(MY_COMPILER_ID "${CMAKE_CXX_COMPILER_ID}")
if(NOT CMAKE_CXX_COMPILER_ID)
    set(MY_COMPILER_ID "${CMAKE_C_COMPILER_ID}")
endif()
if(MY_COMPILER_ID STREQUAL "GNU")
    message(STATUS "[YMY] GNU compiler: ${CMAKE_CXX_COMPILER}")
    set(MYTMP_CXX_CMP_OPTS_GCC -finput-charset=utf-8 -fexec-charset=utf-8 -Wall -Wextra -Wpedantic)
    # string(REPLACE ";" "," MY_CXX_CMP_OPTS_NVCC "${MY_CXX_CMP_OPTS_MSVC}")
    list(JOIN MYTMP_CXX_CMP_OPTS_GCC "," MY_CXX_CMP_OPTS_NVCC)
    set(MY_CXX_CMP_OPTS_NVCC "-Xcompiler=${MY_CXX_CMP_OPTS_NVCC}")

    list(JOIN MYTMP_CXX_CMP_OPTS_GCC " " MY_CXX_CMP_OPTS_GCC)
endif()


##xxxxxxxxxxxxxxxxxxx 为NVCC编译器添加警告抑制选项
if(CMAKE_CUDA_COMPILER AND FALSE)
    # 抑制fmt和spdlog相关的DLL接口警告
    set(CUDA_WARNING_SUPPRESSIONS
        -diag-suppress=128  # 抑制fmt中的"loop is not reachable"警告
        -diag-suppress=2417 # 抑制fmt中的constexpr构造函数警告
        -diag-suppress=27   # 抑制fmt中的字符值超出范围警告
        -diag-suppress=1388 # 抑制spdlog中的DLL接口规范不一致警告
        -diag-suppress=1394 # 抑制spdlog中的DLL接口字段警告
    )
    list(JOIN CUDA_WARNING_SUPPRESSIONS " " CUDA_WARNING_SUPPRESSIONS)
    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${CUDA_WARNING_SUPPRESSIONS}")
endif()

#================== apply flags
#---- https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_CXX_CMP_OPTS_MSVC}")
#----
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${MY_CXX_CMP_OPTS_NVCC}")
message(STATUS "[YMY] CMAKE_CUDA_FLAGS => ${CMAKE_CUDA_FLAGS}")